package edu.hawaii.halealohacli.command;

/**
 * Stores data regarding the baseline energy usage of a particular source.
 * This data includes the energy consumption over the course of a day for that source.
 * 
 * @author Branden Ogata
 *
 */

public class Baseline implements Comparable<Baseline> {
  
  /**
   * The name of the source that this Baseline refers to.
   * 
   */
  private String source;

  /**
   * The date which the energy values were taken from.
   * 
   */
  private String date;
  
  /**
   * The twenty-four values of energy consumption over the day.
   * 
   */
  private double[] values;
  
  /**
   * Initializes the Baseline instance.
   * 
   * @param source  The name of the source for the baseline.
   * @param date  The date on which the baseline values of the source were measured.
   * @param values  The values used to initialize the array.
   * 
   */
  
  public Baseline (String source, String date, double[] values) {
    this.source = source;
    this.date = date;
    
    this.values = new double[24];
    
    for (int i = 0; i < 24; i++) {
      this.values[i] = values[i];
    }
  }

  /**
   * Returns the name of the source for this Baseline.
   * 
   * @return this.source  The name of the source for which baseline values were measured.
   * 
   */
  
  public String getSource() {
    return this.source;
  }
  
  /**
   * Returns the date for this Baseline.
   * 
   * @return this.date  The date on which the values for this Baseline were measured.
   * 
   */
  
  public String getDate() {
    return this.date;
  }
  
  /**
   * Returns the set of baseline values.
   * 
   * @return temp A temporary array used for returning the baseline values.
   * 
   */
  
  public double[] getValues() {
    double[] temp = new double[24];
    
    for (int i = 0; i < 24; i++) {
      temp[i] = this.values[i];
    }
    
    return temp;
  }
  
  /**
   * Sets a particular value in values.
   * 
   * @param hour  The hour at which to assign the new value.
   * @param newValue  The new value to assign.
   * 
   */
  
  public void setValues(int hour, double newValue) {
    this.values[hour] = newValue;
  }
  
  /**
   * Compares this Baseline to the parameter.
   * 
   * @param obj The object to compare this Baseline to.
   * 
   * @return  True if this object is equal to the parameter, else false.
   * 
   */
  
  @Override
  public boolean equals(Object obj) {
    boolean isEqual = false;
    
    if (obj == this) {
      isEqual = true;
    }
    else if (obj instanceof Baseline) {
      Baseline temp = (Baseline) obj;

      // If the source and date are equal, then the objects are equal
      if ((this.source.equals(temp.getSource())) && (this.date.equals(temp.getDate()))) {
        isEqual = true;
      }
    }

    return (isEqual);    
  }
  
  /**
   * Returns a hash code based on this Baseline object.
   * Based on the suggestions in Effective Java, Chapter 3.
   * 
   * @return An int equal to the hash code for this Baseline object.
   * 
   */
  
  @Override
  public int hashCode() {
    int result = 17;
    int combination = this.source.hashCode() + this.date.hashCode();
    result = 37 * result + combination;
    return (result);    
  }
  
  /**
   * Compares this object with another Baseline object.
   * The comparison is based on the source and date of the Baseline objects.
   * 
   * @param baseline  The Baseline object to compare this object to.
   * 
   * @return  0 if this object and the parameter are equal.
   *          1 if this object is greater than the parameter object.
   *          -1 if this object is less than the parameter object.
   *          
   */
  
  @Override
  public int compareTo(Baseline baseline) {
    // If this object is the parameter, then it is the same object by definition
    if (this == baseline) {
      return 0;
    }
    
    // Compare sources
    if (this.source.compareTo(baseline.getSource()) > 0) {
      return 1;
    }
    else if (this.source.compareTo(baseline.getSource()) < 0) {
      return -1;
    }
    
    // Compare dates
    if (this.date.compareTo(baseline.getDate()) > 0) {
      return 1;
    }
    else if (this.date.compareTo(baseline.getDate()) < 0) {
      return -1;
    }
    
    return 0;
  }
  
  /**
   * Returns a String representation of this Baseline object.
   * 
   * @return  The identifying information of this Baseline object, in the format:
   *          "[source] on [date]"
   *          
   */
  
  @Override
  public String toString() {
    return this.source + " on " + this.date;
  }
}